home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
Bitmap Libraries 2.0
/
Examples
/
Rotation
/
Rotation.c
< prev
next >
Wrap
Text File
|
1996-03-05
|
10KB
|
404 lines
/* File Rotation.c Copyright (C) 1996 by John R. Montbriand. All Rights Reserved. */
/* File Rotation.c
Copyright (C) 1996 by John Montbriand. All Rights Reserved.
Distribute freely in areas where the laws of copyright apply.
Use at your own risk.
Do not distribute modified copies.
These various BitMap libraries and examples are for free!
See the accompanying file BitMap.txt for details.
*/
/* written in Geneva 9, tabs at 4 */
/* •••••••••••••••••••••• INCLUDES •••••••••••••••••••••• */
#include <Types.h>
#include <QuickDraw.h>
#include <Fonts.h>
#include <Windows.h>
#include <Menus.h>
#include <TextEdit.h>
#include <Dialogs.h>
#include <AppleEvents.h>
#include <TextUtils.h>
#include <OSUtils.h>
#include <ToolUtils.h>
#include <Desk.h>
#include <Memory.h>
#include <Errors.h>
#include <Gestalt.h>
#include <Traps.h>
#include <SegLoad.h>
#include "BitMap.h"
/* •••••••••••••••••••••• CONSTANTS •••••••••••••••••••••• */
#define kAboutBoxID 128
#define kErrorBoxID 129
#define kMainWindID 128
#define kMenuBarID 128
#define mApple 128
#define iAbout 1
#define iAccessoryOne 3
#define mFile 129
#define iQuit 1
#define mEdit 130
#define iUndo 1
#define iCut 3
#define iCopy 4
#define iPaste 5
#define iClear 6
/* •••••••••••••••••••••• GLOBALS •••••••••••••••••••••• */
Boolean PROGRAM_RUNNING = true;
Boolean PROGRAM_FRONT = true;
Boolean HAS_APPLEEVENTS = false;
Boolean HAS_WAITNEXTEVENT = false;
QDGlobals qd;
DialogPtr gABOUTBOX = NULL;
WindowPtr gMAIN_WINDOW = NULL;
/* •••••••••••••••••••••• ERROR HANDLER •••••••••••••••••••••• */
/* Terminate, displays an error box containing the error number and then terminates
the application. */
void Terminate(OSErr err) {
Str255 s;
NumToString(err, s);
ParamText(s, NULL, NULL, NULL);
Alert(kErrorBoxID, NULL);
ExitToShell();
}
/* •••••••••••••••••••••• THE EXAMPLE PART •••••••••••••••••••••• */
/* NOTE: all of the example code to do with bitmaps is included in this part of the
program. The rest of the program has to do with the usual things that go into
applications. */
/*DrawWindowContents is called in response to every update event for the main
window. this is the part where we do drawing in the bitmaps */
void DrawWindowContents(WindowPtr wp) {
PicHandle pic;
BitMap *bits, *rbits, *sbits;
short the_top;
BitMapPort* bmp;
EraseRect(&wp->portRect);
/* logo picture */
bits = PICTToBitMap(GetPicture(128));
if (bits != NULL) {
rbits = RotateBitMap(bits, bits->bounds.right/2, bits->bounds.bottom/2, 23.0);
if (rbits != NULL) {
PlotBitMap(rbits, 0, 0, srcOr);
KillBitMap(rbits);
}
the_top = bits->bounds.bottom;
KillBitMap(bits);
}
/* hello world string */
bits = StringToBitMap(0, 12, 0, "\pHello World");
if (bits != NULL) {
PlotBitMap(bits, (200-bits->bounds.right)/2, the_top, srcOr);
rbits = FlipVertical(bits);
if (rbits != NULL) {
PlotBitMap(rbits, (200-bits->bounds.right)/2, the_top + bits->bounds.bottom, srcOr);
KillBitMap(rbits);
}
rbits = FlipHorizontal(bits);
if (rbits != NULL) {
PlotBitMap(rbits, (200-bits->bounds.right)/2, the_top + bits->bounds.bottom*2, srcOr);
KillBitMap(rbits);
}
rbits = RotateLeft(bits);
if (rbits != NULL) {
PlotBitMap(rbits, 20, the_top + 20, srcOr);
KillBitMap(rbits);
}
rbits = RotateRight(bits);
if (rbits != NULL) {
PlotBitMap(rbits, 200-20-rbits->bounds.right, the_top + 20, srcOr);
KillBitMap(rbits);
}
rbits = NewBitMap(bits->bounds.right, bits->bounds.right);
if (rbits != NULL) {
WithBitMap(rbits, bmp) {
PlotBitMap(bits, 0, (rbits->bounds.bottom - bits->bounds.bottom)/2, srcOr);
}
sbits = RotateBitMap(rbits, rbits->bounds.right/2, rbits->bounds.bottom/2, -37.0);
if (sbits != NULL) {
PlotBitMap(sbits, (200-bits->bounds.right)/2, the_top + bits->bounds.bottom*3, srcOr);
KillBitMap(sbits);
}
KillBitMap(rbits);
}
KillBitMap(bits);
}
}
/*ClickWindowContents is called every time a mouse down event occurs in the
main program window allowing for some interaction. */
void ClickWindowContents(WindowPtr wp, Point where) {
}
/* InitExample is called at program startup after the main window has been
created to allow the example to set itself up. I put it here so all the example
code would be together in one section. */
OSErr InitExample(WindowPtr wp) {
return noErr;
}
/* •••••••••••••••••••••• MENU COMMANDS •••••••••••••••••••••• */
/* HandleMenuCommand is called after MenuKey or MenuSelect to handle the processing
of menu commands. Here there aren't too many, just the standard ones */
void HandleMenuCommand(short menu, short item) {
if (menu == mApple) {
if (item == iAbout) {
if (gABOUTBOX != NULL)
SelectWindow(gABOUTBOX);
else gABOUTBOX = GetNewDialog(kAboutBoxID, NULL, (WindowPtr) (-1));
} else if (item >= iAccessoryOne) {
Str255 itemString;
GetItem(GetMHandle(menu), item, itemString);
OpenDeskAcc(itemString);
}
} else if (menu == mFile) {
switch (item) {
case iQuit:
PROGRAM_RUNNING = false;
break;
}
} else if (menu == mEdit) {
SystemEdit(item-1);
}
HiliteMenu(0);
}
/* MenuPreflightCheck is called immediately before MenuKey or MenuSelect. In your
application you would use this routine to appropriately enable or disable different
commands depending on what can be done at the time of the mouse click or key
command. */
void MenuPreflightCheck(void) {
/* none here*/
}
/* •••••••••••••••••••••• EVENT HANDLING •••••••••••••••••••••• */
/* HandleMouseDownEvent is called to process mouse down events */
void HandleMouseDownEvent(EventRecord *ev) {
WindowPtr target;
switch ( FindWindow(ev->where, &target) ) {
case inDesk:
break;
case inSysWindow:
SystemClick(ev, target);
break;
case inContent:
if (target != FrontWindow())
SelectWindow(target);
else if (target == gMAIN_WINDOW) {
Point where;
where = ev->where;
SetPort(target);
GlobalToLocal(&where);
ClickWindowContents(target, where);
}
break;
case inDrag:
{ Rect r = qd.screenBits.bounds;
if (target != FrontWindow()) SelectWindow(target);
SetPort(target);
InsetRect(&r, 4, 4);
r.top += 20;
DragWindow(target, ev->where, &r);
}
break;
case inGoAway:
if (TrackGoAway(target, ev->where)) {
if (target == gABOUTBOX) {
DisposeDialog(gABOUTBOX);
gABOUTBOX = NULL;
} else PROGRAM_RUNNING = false;
}
break;
case inMenuBar:
{ long mnRes;
MenuPreflightCheck();
if (HiWord(mnRes = MenuSelect(ev->where)) != 0)
HandleMenuCommand(HiWord(mnRes), LoWord(mnRes));
}
break;
}
}
/* SystemSwapTask can be called from anywhere in your application. basically it collects
events and gives the system time to do its thing. */
void SystemSwapTask(void) {
EventRecord ev;
/* get the next event */
if (HAS_WAITNEXTEVENT) {
if (!WaitNextEvent(everyEvent, &ev, 0, NULL)) ev.what = nullEvent;
} else {
if (!GetNextEvent(everyEvent, &ev)) ev.what = nullEvent;
SystemTask();
}
if ((ev.what == keyDown || ev.what == autoKey) && (ev.modifiers & cmdKey) != 0) {
long mnRes;
MenuPreflightCheck();
if (HiWord(mnRes = MenuKey((char) (ev.message & charCodeMask))) != 0)
HandleMenuCommand(HiWord(mnRes), LoWord(mnRes));
} else if (IsDialogEvent(&ev)) {
DialogPtr theDialog;
short itemHit;
DialogSelect(&ev, &theDialog, &itemHit);
} else if (ev.what == mouseDown) {
HandleMouseDownEvent(&ev);
} else if (ev.what == updateEvt) {
WindowPtr wp;
wp = (WindowPtr) ev.message;
SetPort(wp);
BeginUpdate(wp);
DrawWindowContents(wp);
EndUpdate(wp);
} else if (ev.what == kHighLevelEvent) {
if (HAS_APPLEEVENTS)
AEProcessAppleEvent(&ev);
} else if (ev.what == osEvt) {
if (((ev.message >> 24) & 0x0FF) == suspendResumeMessage)
PROGRAM_FRONT = (ev.message & resumeFlag) != 0;
}
}
/* •••••••••••••••••••••• APPLE EVENTS •••••••••••••••••••••• */
/* QuitEventHandler called for quit apple events. all we do here is set the running
flag to false */
pascal OSErr QuitEventHandler(const AppleEvent *appleEvt, AppleEvent* reply, long refcon) {
DescType retType;
Size actSize;
OSErr err;
err = AEGetAttributePtr(appleEvt, keyMissedKeywordAttr, typeWildCard, &retType, NULL, 0, &actSize);
if (err == errAEDescNotFound) {
PROGRAM_RUNNING = false;
return noErr;
} else if (err == noErr)
return errAEEventNotHandled;
else return err;
}
/* •••••••••••••••••••••• TEST FOR TRAPS •••••••••••••••••••••• */
unsigned short NumToolboxTraps(void) {
if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
return 0x0200;
else return 0x0400;
}
TrapType FindTrapType(unsigned short theTrap) {
if (theTrap & 0x0800)
return ToolTrap;
else return OSTrap;
}
Boolean TrapAvailable(unsigned short theTrap) {
unsigned short localTrap = theTrap;
TrapType tType = FindTrapType(localTrap);
if ( tType == ToolTrap ) {
localTrap &= 0x07FF;
if ( localTrap >= NumToolboxTraps() )
localTrap = _Unimplemented;
}
return NGetTrapAddress(localTrap, tType) != NGetTrapAddress(_Unimplemented, ToolTrap);
}
/* •••••••••••••••••••••• MAIN PROGRAM •••••••••••••••••••••• */
void main(void) {
OSErr err;
long response;
/* determine features of the machine */
if (Gestalt(gestaltAppleEventsAttr, &response) != noErr) response = 0;
HAS_APPLEEVENTS = ((response & (1<<gestaltAppleEventsPresent)) != 0);
HAS_WAITNEXTEVENT = TrapAvailable(_WaitNextEvent);
/* initialize the toolbox, etc.. */
SetApplLimit( GetApplLimit() - (8*1024) );
MaxApplZone();
InitGraf(&qd.thePort);
InitFonts();
InitWindows();
TEInit();
InitMenus();
InitDialogs(NULL);
InitCursor();
if (HAS_APPLEEVENTS) {
err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
NewAEEventHandlerProc(QuitEventHandler), 0, false);
if (err != noErr) goto bail;
}
SetMenuBar(GetNewMBar(kMenuBarID));
AddResMenu(GetMHandle(mApple), 'DRVR');
DrawMenuBar();
gMAIN_WINDOW = GetNewWindow(kMainWindID, NULL, (WindowPtr) (-1));
SetPort(gMAIN_WINDOW);
err = InitExample(gMAIN_WINDOW);
/* set up some globals */
PROGRAM_RUNNING = true;
PROGRAM_FRONT = true;
/* loop until PROGRAM_RUNNING is false */
while (PROGRAM_RUNNING)
SystemSwapTask();
return;
bail:
Terminate(err);
}
/* end File BitMap.c */